package com.his.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.his.commons.core.exception.HisException;
import com.his.commons.core.util.TimeUtil;
import com.his.commons.web.util.WebBeanUtils;
import com.his.controller.form.*;
import com.his.controller.info.*;
import com.his.mapper.UserInfoMapper;
import com.his.model.Schedule;
import com.his.mapper.ScheduleMapper;
import com.his.model.UserInfo;
import com.his.service.DepartmentService;
import com.his.service.DisagnosisRoomService;
import com.his.service.ScheduleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.his.service.UserInfoService;
import com.his.util.DataAndTimeUtil;
import com.his.util.StaticDataUtil;
import com.his.util.StringToTrimUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 梅津铧
 * @since 2022-03-22
 */
@Service
public class ScheduleServiceImpl extends ServiceImpl<ScheduleMapper, Schedule> implements ScheduleService {

    @Resource
    private ScheduleMapper scheduleMapper;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private DisagnosisRoomService disagnosisRoomService;
    @Resource
    private ScheduleService scheduleService;

    /**
     * 创建某诊室的医生排班信息
     *
     * @param newScheduleForm 排班信息
     */
    @Override
    public boolean increaseSchedules(NewScheduleForm newScheduleForm) throws HisException {
        //判断员工姓名是否含空字符
        if(!StringToTrimUtil.StringToTrim(newScheduleForm.getScheduleUserName())) throw new HisException("请填写正确信息",500);

        //判断医生信息是否正确
        LoginUserInfo loginUserInfo = userInfoService.obtainUserInfo(newScheduleForm.getScheduleUserId());
        if(null == loginUserInfo | !loginUserInfo.getUserName().equals(newScheduleForm.getScheduleUserName())) throw new HisException("该员工不存在",500);

        //判断科室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(String.valueOf(newScheduleForm.getDepartmentId()));
        if(null == departmentInfo) throw new HisException("该科室不存在",500);
        //判断诊室是否存在
        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == newScheduleForm.getDisagnosisId()) throw new HisException("该科室存在下属诊室，请填写诊室信息",500);
            List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(departmentInfo.getDepartmentId());
            if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("诊室不存在",500);
            boolean dis = false;
            for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                if(disagnosisRoomInfo.getDisagnosisId()==newScheduleForm.getDisagnosisId()) dis=true;
            }
            if(!dis) throw new HisException("诊室不存在",500);
        }else {
            if(newScheduleForm.getDisagnosisId()>0) throw new HisException("该科室无下属诊室",500);
        }

        //创建排班
        ArrayList<Schedule> schedules = new ArrayList<>();
        for (String s : StaticDataUtil.DayAndTime()) {
            Schedule schedule = new Schedule();
            schedule.setScheduleUserId(newScheduleForm.getScheduleUserId());
            schedule.setScheduleUserName(newScheduleForm.getScheduleUserName());
            schedule.setDepartmentId(newScheduleForm.getDepartmentId());
            if(departmentInfo.getDepartmentState().equals("是")){
                schedule.setDisagnosisId(newScheduleForm.getDisagnosisId());
            }
            schedule.setScheduleState(0);
            schedule.setWorkTime(s);
            schedules.add(schedule);
        }
        boolean integer = saveBatch(schedules);

        return integer;
    }

    /**
     * 注册某诊室医生的排班信息
     *
     * @param form 排班信息
     */
    @Override
    public boolean modifyByInfo(ScheduleInfoForm form) throws HisException {
        //判断医生信息是否正确
        LoginUserInfo loginUserInfo = userInfoService.obtainUserInfo(form.getCreatePersonId());
        if(null == loginUserInfo) throw new HisException("该员工不存在",500);

        //判断科室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(String.valueOf(form.getDepartmentId()));
        if(null == departmentInfo) throw new HisException("该科室不存在",500);
        //判断诊室是否存在
        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == form.getDisagnosisId()) throw new HisException("该科室存在下属诊室，请填写诊室信息",500);
            List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(departmentInfo.getDepartmentId());
            if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("诊室不存在",500);
            boolean dis = false;
            for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                if(disagnosisRoomInfo.getDisagnosisId()==form.getDisagnosisId()) dis=true;
            }
            if(!dis) throw new HisException("诊室不存在",500);
        }else {
            if(form.getDisagnosisId()>0) throw new HisException("该科室无下属诊室",500);
        }

        //判断医生是否属于该科室及诊室
        ArrayList<Integer> integers = new ArrayList<>();
        for (UserScheduleForm scheduleUserId : form.getScheduleUserIds()) {
            integers.add(scheduleUserId.getScheduleUserId());
        }
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            wrapper.eq("department_id",form.getDepartmentId()).eq("disagnosis_id",form.getDisagnosisId()).in("user_job_num",integers);
        }else {
            wrapper.eq("department_id", form.getDepartmentId()).in("user_job_num", integers);
        }
        List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
        if(null == userInfos) throw new HisException("操作医生不存在",500);
        if(userInfos.size()!=integers.size()) throw new HisException("部分医生不属于该诊室，请核查",500);

        //更新排班信息
        ScheduleClearForm scheduleClearForm = new ScheduleClearForm();
        if(null != form.getCreatePersonId()){
            scheduleClearForm.setCreatePersonId(form.getCreatePersonId());
        }
        scheduleClearForm.setDepartmentId(form.getDepartmentId());
        scheduleClearForm.setDisagnosisId(form.getDisagnosisId());
        ArrayList<Integer> ints = new ArrayList<>();
        for (UserScheduleForm scheduleUserId : form.getScheduleUserIds()) {
            ints.add(scheduleUserId.getScheduleUserId());
        }
        scheduleClearForm.setScheduleUserIds(ints);
        boolean b = this.modifyState(scheduleClearForm);
        if(!b) throw new HisException("更新科室信息失败",500);

        for (UserScheduleForm scheduleUserId : form.getScheduleUserIds()) {
            Schedule schedule = new Schedule();
            schedule.setCreatePersonId(form.getCreatePersonId());
            schedule.setDepartmentId(form.getDepartmentId());
            if(departmentInfo.getDepartmentState().equals("是")){
                schedule.setDisagnosisId(form.getDisagnosisId());
            }
            schedule.setScheduleState(1);
            schedule.setCreateTime(TimeUtil.getTimeString());
            QueryWrapper<Schedule> scheduleQueryWrapper = new QueryWrapper<>();
            scheduleQueryWrapper.eq("schedule_user_id",scheduleUserId.getScheduleUserId()).in("work_time",scheduleUserId.getWorkTimes());
            if(!update(schedule,scheduleQueryWrapper)) throw new HisException("排班信息更新失败",500);
        }

        return true;
    }

    /**
     * 根据科室、日期信息获取医生信息
     *
     * @param form 科室、日期信息
     * @return 医生信息
     */
    @Override
    public List<UserByDayInfo> obtainByDay(ScheduleByDayForm form) throws HisException{
        //判断是否字段内容为空
        if(null==form.getDisagnosisRoomId() | null==form.getDepartmentId() | null==form.getDate() | null==form.getTime()) throw new HisException("请输入正确信息",500);
        if(!StringToTrimUtil.StringToTrim(String.valueOf(form.getDepartmentId())) | !StringToTrimUtil.StringToTrim(String.valueOf(form.getDisagnosisRoomId()))
            | !StringToTrimUtil.StringToTrim(form.getDate()) | !StringToTrimUtil.StringToTrim(form.getTime())
        ) throw new HisException("请输入正确信息",500);
        String pattern = "^\\d{4}-\\d{1,2}-\\d{1,2}";
        boolean isMatch = Pattern.matches(pattern, form.getDate());
        if(!isMatch) throw new HisException("日期格式不符合要求，应为：yyyy-MM-dd",500);

        //判断科室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(String.valueOf(form.getDepartmentId()));
        if(null == departmentInfo) throw new HisException("该科室不存在",500);
        //判断诊室是否存在
        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == form.getDisagnosisRoomId()) throw new HisException("该科室存在下属诊室，请填写诊室信息",500);
            List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(departmentInfo.getDepartmentId());
            if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("诊室不存在",500);
            boolean dis = false;
            for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                if(disagnosisRoomInfo.getDisagnosisId()==form.getDisagnosisRoomId()) dis=true;
            }
            if(!dis) throw new HisException("诊室不存在",500);
        }else{
            if(null != form.getDisagnosisRoomId()) throw new HisException("该科室无下属诊室",500);
        }

        //获取医生信息
        String dataAndtime = null;
        try {
            dataAndtime = DataAndTimeUtil.getDayAndNum(form.getDate())+form.getTime();
        } catch (Exception e) {
            throw new HisException("当前服务器繁忙，请稍后重试",500);
        }
        List<UserByDayInfo> schedules = scheduleMapper.obtainByDayInfo("门诊医生",form.getDepartmentId(),form.getDisagnosisRoomId(),dataAndtime);
        if(null == schedules | schedules.size()==0) throw new HisException("未获取到该时间的医生信息",500);

        return schedules;
    }

    /**
     * 清空某诊室医生的排班信息
     *
     * @param form 诊室医生信息
     */
    @Override
    public boolean modifyState(ScheduleClearForm form) throws HisException {
        //判断参数是否满足要求
        if( !StringToTrimUtil.StringToTrim(String.valueOf(form.getDepartmentId())) | form.getScheduleUserIds().size()<=0)
            throw new HisException("请输入正确信息",500);

        //判断科室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(String.valueOf(form.getDepartmentId()));
        if(null == departmentInfo) throw new HisException("该科室不存在",500);
        //判断诊室是否存在
        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == form.getDisagnosisId()) throw new HisException("该科室存在下属诊室，请填写诊室信息",500);
            List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(departmentInfo.getDepartmentId());
            if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("诊室不存在",500);
            boolean dis = false;
            for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                if(disagnosisRoomInfo.getDisagnosisId()==form.getDisagnosisId()) dis=true;
            }
            if(!dis) throw new HisException("诊室不存在",500);
        }else{
            if(null != form.getDisagnosisId()){
                if(form.getDisagnosisId()>0) throw new HisException("该科室无下属诊室",500);
            }
        }

        //判断医生是否属于该科室及诊室
        ArrayList<Integer> integers = new ArrayList<>();
        for (Integer scheduleUserId : form.getScheduleUserIds()) {
            integers.add(scheduleUserId);
        }
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            wrapper.eq("department_id",form.getDepartmentId()).eq("disagnosis_id",form.getDisagnosisId()).in("user_job_num",integers);
        }else{
            wrapper.eq("department_id",form.getDepartmentId()).in("user_job_num",integers);
        }
        List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
        if(null == userInfos) throw new HisException("操作医生不存在",500);
        if(userInfos.size()!=integers.size()) throw new HisException("部分医生不属于该诊室，请核查",500);

        //清空某诊室医生的排班信息
        Schedule schedule = new Schedule();
        schedule.setScheduleState(0);
        schedule.setCreateTime(TimeUtil.getTimeString());
        schedule.setCreatePersonId(form.getCreatePersonId());
        QueryWrapper<Schedule> scheduleQueryWrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            scheduleQueryWrapper.eq("department_id",form.getDepartmentId()).eq("disagnosis_id",form.getDisagnosisId()).in("schedule_user_id",form.getScheduleUserIds());
        }else{
            scheduleQueryWrapper.eq("department_id",form.getDepartmentId()).in("schedule_user_id",form.getScheduleUserIds());
        }
        int update = scheduleMapper.update(schedule, scheduleQueryWrapper);

        return update>0? true:false;
    }

    /**
     * 根据科室、诊室查询排班信息
     *
     * @param departmentId     科室id
     * @param disagnosisRoomId 诊室id
     * @return 排班信息
     */
    @Override
    public List<ScheduleInfo> obtainSchedule(Integer departmentId, Integer disagnosisRoomId) throws HisException {
        //校验参数
        if(!StringToTrimUtil.StringToTrim(String.valueOf(departmentId)) | !StringToTrimUtil.StringToTrim(String.valueOf(disagnosisRoomId))) throw new HisException("请输入正确信息",500);

        //判断科室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(String.valueOf(departmentId));
        if(null == departmentInfo) throw new HisException("该科室不存在",500);
        //判断诊室是否存在
        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == disagnosisRoomId) throw new HisException("该科室存在下属诊室，请填写诊室信息",500);
            List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(departmentInfo.getDepartmentId());
            if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("诊室不存在",500);
            boolean dis = false;
            for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                if(disagnosisRoomInfo.getDisagnosisId()==disagnosisRoomId) dis=true;
            }
            if(!dis) throw new HisException("诊室不存在",500);
        }else{
            if(null != disagnosisRoomId) throw new HisException("该科室无下属诊室",500);
        }

        //查询排班信息
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            userInfoQueryWrapper.eq("department_id",departmentId).eq("disagnosis_id",disagnosisRoomId);
        }else{
            userInfoQueryWrapper.eq("department_id",departmentId);
        }
        List<UserInfo> userInfos = userInfoMapper.selectList(userInfoQueryWrapper);
        if(null == userInfos | userInfos.size()==0) throw new HisException("该科室无医生",500);
        List<ScheduleInfo> scheduleInfos = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            QueryWrapper<Schedule> wrapper = new QueryWrapper<>();
            if(departmentInfo.getDepartmentState().equals("是")){
                wrapper.eq("department_id",departmentId).eq("disagnosis_id",disagnosisRoomId).eq("schedule_user_id",userInfo.getUserJobNum()).eq("schedule_state",1);
            }else{
                wrapper.eq("department_id",departmentId).eq("schedule_user_id",userInfo.getUserJobNum()).eq("schedule_state",1);
            }
            List<Schedule> schedules = scheduleMapper.selectList(wrapper);

            if(null != schedules && schedules.size()>0){
                List<String> workTime = new ArrayList<>();
                for (Schedule schedule : schedules) {
                    workTime.add(schedule.getWorkTime());
                }
                ScheduleInfo scheduleInfo = new ScheduleInfo();
                scheduleInfo.setScheduleUserId(userInfo.getUserJobNum());
                scheduleInfo.setScheduleUserName(userInfo.getUserName());
                scheduleInfo.setWorkTimes(workTime);
                System.out.println(scheduleInfo);
                scheduleInfos.add(scheduleInfo);
            }
        }

        return scheduleInfos;
    }

    /**
     * 清除某科室的排班信息
     * @param scheduleUserIds  员工工号
     * @param departmentId  科室id
     * @param disagnosisId  诊室id
     */
    @Override
    public boolean logoutSchedule(List<Integer> scheduleUserIds, Integer departmentId, Integer disagnosisId) throws HisException {
        //判断参数是否满足要求
        if(null == departmentId | scheduleUserIds.size()<=0) throw new HisException("请输入正确信息",500);

        //判断科室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(String.valueOf(departmentId));
        if(null == departmentInfo) throw new HisException("该科室不存在",500);
        //判断诊室是否存在
        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == disagnosisId) throw new HisException("该科室存在下属诊室，请填写诊室信息",500);
            List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(departmentInfo.getDepartmentId());
            if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("诊室不存在",500);
            boolean dis = false;
            for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                if(disagnosisRoomInfo.getDisagnosisId()==disagnosisId) dis=true;
            }
            if(!dis) throw new HisException("诊室不存在",500);
        }else{
            if(null != disagnosisId){
                if(disagnosisId>0) throw new HisException("该科室无下属诊室",500);
            }
        }

        //判断医生是否属于该科室及诊室
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            wrapper.eq("department_id",departmentId).eq("disagnosis_id",disagnosisId).in("user_job_num",scheduleUserIds);
        }else{
            wrapper.eq("department_id",departmentId).in("user_job_num",scheduleUserIds);
        }
        List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
        if(null == userInfos) throw new HisException("操作医生不存在",500);
        System.out.println(userInfos);
        if(userInfos.size()!=scheduleUserIds.size()) throw new HisException("部分医生不属于该诊室，请核查",500);

        //删除排班信息
        QueryWrapper<Schedule> scheduleWrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            scheduleWrapper.eq("department_id",departmentId).eq("disagnosis_id",disagnosisId).in("schedule_user_id",scheduleUserIds);
        }else{
            scheduleWrapper.eq("department_id",departmentId).in("schedule_user_id",scheduleUserIds);
        }
        int delete = scheduleMapper.delete(scheduleWrapper);

        return delete>0? true:false;
    }
}
